#ifndef _COMM_EVENT_H_
#define _COMM_EVENT_H_

#include <time.h>

#ifdef _WIN32
#include <winsock2.h>
#include <windows.h>
#else
#define SOCKET int 
#define INVALID_SOCKET -1
#define CLOSESOCKET close
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef struct network network;

typedef void (*network_read_func)(network * net, SOCKET fd, void * ctx);
typedef void (*network_write_func)(network * net, SOCKET fd, void * ctx);
typedef void (*network_connect_func)(network * net, SOCKET fd,
		int error, void * ctx);
typedef void (*network_accept_func)(network * net,
		SOCKET listen_fd, SOCKET new_fd,
		const char * ip,
		unsigned short port, void * ctx);
typedef void (*network_timer_func)(network * net, time_t now, void * ctx);

#define NETWORK_LT 0
#define NETWORK_ET 1

#define NETWORK_READ    0x01
#define NETWORK_WRITE   0x02 
#define NETWORK_TIMER   0x04 

SOCKET listen_on(const char * ip, unsigned short port);
SOCKET connect_to(const char * ip, unsigned short port, int * done);

network * network_create(int type);
const char * network_desc(network * net);

int network_loop(network * net);
int network_step(network * net);
void network_exit(network * net);

void network_destory(network * net);

SOCKET network_connect(network * net, 
                    const char * ip, int port,
                    network_connect_func on_connected,
                    void * ctx);

SOCKET network_listen(network * net, 
                   const char * ip, int port,
                   network_accept_func on_accept,
                   void * ctx);

int network_set_listen_socket(network * net, SOCKET fd,
                   network_accept_func on_accept,
                   void * ctx);

int network_set(network * net, SOCKET fd,
                network_read_func on_read,
                network_write_func on_write,
                void * ctx);

int network_enable(network * net, SOCKET fd, int flag);
int network_disable(network * net, SOCKET fd, int flag);

int network_timer(network * net,
                  network_timer_func on_timer,
                  void * ctx);

int network_disable_timer(network * net);
int network_enable_timer(network * net);

int network_del(network * net, SOCKET fd);
void * network_userdata(network * net, SOCKET fd);

#ifdef __cplusplus
}
#endif

#endif  // _COMM_EVENT_H_
